/**
 * 
 */
package research.sbookmarking.process;

import java.util.*;
import org.afox.util.*;
import research.sbookmarking.*;

import org.connotea.*;

/**
 * This class controller for processing the data retrieved from Connotea.org
 * <p> 
 * @author <A HREF="mailto:aatleung@gmail.com">Albert Leung</a>
 * @version 1.0
 */
public class ProcessController {

	private static ProcessController anInstance = null;
	
	/**
	 * The only way to instantiate this class is through 
	 * {@link #getInstance() getInstance}
	 */
	private ProcessController() {
	}

	/**
	 * Ensures that there is only one ProcessController instance. If an
	 * instance already exists it return the address of that instance
	 * otherwise it will instantiate an instance and save it.
	 * <p>
	 * @return an instance of this object.
	 */
	public static ProcessController getInstance() {
		if (anInstance==null) {
			anInstance = new ProcessController();
		}
		
		return anInstance;
	}

	private void increment (HashMap freq, Object result) {
		Long value = null;
		
		value=(Long)freq.remove(result);
		if (value==null){
			freq.put(result, new Long(1));
		}
		else {
			long val = value.longValue();
			freq.put(result,new Long(++val));
		}
	}
	
	private void calcFreq (DataContainer data){
		//number of times an URL has been bookmarked
		HashMap bookmarkFreq = new HashMap();
		
		//number of times a user posted
		HashMap userFreq = new HashMap();
		
		//the list of users for each URL
		HashMap urlUser = new HashMap();
		
		Iterator results = data.getQueryResults().iterator();
		
		while (results.hasNext()){
			Bookmark query = ((Post)results.next()).getBookmark();
			
			if (bookmarkFreq.get(query)==null){
				bookmarkFreq.put(query, new Long(query.getPostCount()));
				urlUser.put(query, query.getPostedBy());
			}
			increment (userFreq,query.getFirstUser());
		}
		
		data.setFreqBookmarks(bookmarkFreq);
		data.setUserFreq(userFreq);
		data.setUrlUser(urlUser);
	}
	
/*
	private void calcTags (DataContainer data){
		//tags for each post
		HashMap tagsFreq = new HashMap();
		
		Iterator results = data.getQueryResults().iterator();
		
		while (results.hasNext()){
			Post aPost = (Post)results.next();
			tagsFreq.put(aPost,aPost.getSubjects());
			
			data.setFreqTags(tagsFreq);
		}
	}
*/
	
	private String getKey(Post aPost, String command){
		if (command.equals("getBookmark")){
			return aPost.getBookmark().getLink().toString();
		}
		else if (command.equals("getCreator")) {
			return aPost.getCreator();
		}
		return null;
	}
	
	private Object calcTags (String command, DataContainer data){
		// tags for each key (i.e. post or user)
		HashMap keys = new HashMap();
		
		Iterator results = data.getQueryResults().iterator();
		
		while (results.hasNext()){
			Post aPost = (Post)results.next();
			
/*
			Object obj = null;
			if (command.equals("")) {
			
				obj = aPost;
			}
			else {
				obj = RMethod.invoke(aPost, command, new ArrayList());
			}
*/
			String key = getKey(aPost, command);
			HashMap tagsFreq = (HashMap)keys.get(key);
			if (tagsFreq == null) {
				tagsFreq = new HashMap();
			}

			Iterator tags = aPost.getSubjects().iterator();
			while (tags.hasNext()){
				increment (tagsFreq, tags.next());
			}
			keys.put(key, tagsFreq);
		}
		
		return keys;
	}
	
	public void getUsers (DataContainer dataContainer){
		Iterator data = dataContainer.getQueryResults().iterator();
		List username = new ArrayList();
		
		while (data.hasNext()){
			Post aPost = (Post)data.next();
			if (username.contains(aPost.getCreator())==false){
				username.add(aPost.getCreator());
			}
		}
		
		List param = new ArrayList();
		param.add(username);
		RMethod.invoke(dataContainer,"setUniqueUsers",param);
	}

/*
	public void processDataURL (DataContainer data) {
		calcFreq(data);
		calcTags(data); 
	}
*/
	
	public void processData (List dataContainers){
		Iterator iterator = dataContainers.iterator();
		
		while (iterator.hasNext()){
			DataContainer aDataContainer = (DataContainer)iterator.next();
			calcFreq(aDataContainer);
			aDataContainer.setFreqTags((HashMap)calcTags("getBookmark",aDataContainer));
			aDataContainer.setUserTags((HashMap)calcTags("getCreator",aDataContainer));

			//List parameters = new ArrayList();
			//parameters.add(dataContainers);
			//RMethod.invoke(this, "processData"+aDataContainer.getQueryName(), parameters);
		}
	}

	/* For Debugging purposes
	 * 
	 */
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
}
